package com.shiguiwu.springmybatis.spring.aop.cglib;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;

/**
 * @description: callbak
 * 1. Cglib根据父类,Callback, Filter 及一些相关信息生成key
 * 2. 然后根据key 生成对应的子类的二进制表现形式
 * 3. 使用ClassLoader装载对应的二进制,生成Class对象,并缓存
 * 4. 最后实例化Class对象,并缓存
 * @author: stone
 * @date: Created by 2021/5/18 19:54
 * @version: 1.0.0
 * @pakeage: com.shiguiwu.springmybatis.spring.aop.cglib
 */
public class CglibCallbackObjTest {

    interface Service1 {
        void m1();
    }


    interface Service2 {
        void m2();
    }

    public static class Service implements Service1, Service2 {

        @Override
        public void m1() {
            System.out.println("m1");

        }

        @Override
        public void m2() {
            System.out.println("m2");
        }
    }

    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();

        //设置父类
        enhancer.setSuperclass(Service.class);

        //设置代理对象需要实现的接口
        enhancer.setInterfaces(new Class[]{Service1.class, Service2.class});

        //通过Callback来对被代理方法进行增强
        enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
            long l = System.nanoTime();
            Object result = methodProxy.invokeSuper(o, objects);
            System.out.println(method.getName() + "耗时为：" + (System.nanoTime() - l));
            return result;
        });


        Object proxy = enhancer.create();

        //if (proxy instanceof Service) {
        //    ((Service) proxy).m1();
        //    ((Service) proxy).m2();
        //}

        System.out.println("父类" + proxy.getClass().getSuperclass());

        System.out.println(proxy.getClass());
        System.out.println("创建代理类实现的接口如下：");
        for (Class<?> cs : proxy.getClass().getInterfaces()) {
            System.out.println(cs);
        }


        Enhancer enhancer1 = new Enhancer();

        enhancer1.setSuperclass(proxy.getClass());

        enhancer1.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
            long l = System.nanoTime();
            Object result = methodProxy.invokeSuper(o, objects);
            System.out.println(method.getName() + "耗时11为：" + (System.nanoTime() - l));
            return result;
        });

        Object proxy1 = enhancer1.create();

        System.out.println("父类" + proxy1.getClass().getSuperclass());

        System.out.println(proxy1.getClass());
        //if (proxy1 instanceof Service) {
        //    ((Service) proxy1).m1();
        //    ((Service) proxy1).m2();
        //}
    }


}
